package repository

import (
	"context"
	"jk-time/webook/follow/cache"
	"jk-time/webook/follow/dao"
	"jk-time/webook/follow/domain"
	"jk-time/webook/pkg/logger"
)

type FollowRepository interface {
	// GetFollowee 获取某人的关注列表
	GetFollowee(ctx context.Context, follower, offset, limit int64) ([]domain.FollowRelation, error)
	// FollowInfo 查看关注人的详情
	FollowInfo(ctx context.Context, follower int64, followee int64) (domain.FollowRelation, error)
	// AddFollowRelation 创建关注关系
	AddFollowRelation(ctx context.Context, f domain.FollowRelation) error
	// InactiveFollowRelation 取消关注
	InactiveFollowRelation(ctx context.Context, follower int64, followee int64) error
	GetFollowStatics(ctx context.Context, uid int64) (domain.FollowStatics, error)
}
type followRepository struct {
	dao   dao.FollowDao
	cache cache.FollowCache
	l     logger.Logger
}

func NewFollowRepository(dao dao.FollowDao, cache cache.FollowCache, l logger.Logger) FollowRepository {
	return &followRepository{dao: dao, cache: cache, l: l}
}
func (f followRepository) GetFollowee(ctx context.Context, follower, offset, limit int64) ([]domain.FollowRelation, error) {
	// 你可以考虑在这里缓存关注者列表的第一页
	followerList, err := f.dao.FollowRelationList(ctx, follower, offset, limit)
	if err != nil {
		return nil, err
	}
	res := make([]domain.FollowRelation, 0, len(followerList))
	for _, c := range followerList {
		res = append(res, f.toDomain(c))
	}
	return res, nil
}

func (f followRepository) FollowInfo(ctx context.Context, follower int64, followee int64) (domain.FollowRelation, error) {
	// follow:123:234 => 标签信息，分组信息
	c, err := f.dao.FollowRelationDetail(ctx, follower, followee)
	if err != nil {
		return domain.FollowRelation{}, err
	}
	return f.toDomain(c), nil
}

func (f followRepository) AddFollowRelation(ctx context.Context, follow domain.FollowRelation) error {
	err := f.dao.CreateFollowRelation(ctx, f.toEntity(follow))

	return err
	// 更新缓存里面的关注了多少人，以及有多少粉丝的计数， +1
	//return f.cache.UpdateStaticsInfo(ctx, follow.Follower, follow.Followee, 1)
}

func (f followRepository) InactiveFollowRelation(ctx context.Context, follower int64, followee int64) error {
	err := f.dao.UpdateStatus(ctx, followee, follower, dao.FollowRelationStatusInactive)
	if err != nil {
		return err
	}
	return err
	// -1
	//return f.cache.UpdateStaticsInfo(ctx, follower, followee, -1)
}

func (f followRepository) GetFollowStatics(ctx context.Context, uid int64) (domain.FollowStatics, error) {
	fs, err := f.cache.GetStaticsInfo(ctx, uid)
	if err == nil {
		return fs, err
	}
	fs.Followers, err = f.dao.CntFollower(ctx, uid)
	if err != nil {
		return fs, err
	}
	fs.Followees, err = f.dao.CntFollowee(ctx, uid)
	if err != nil {
		return fs, err
	}
	go func() {
		err := f.cache.SetStaticsInfo(ctx, uid, fs)
		if err != nil {
			f.l.Error("缓存关注统计信息失败", logger.Error(err), logger.Int64("uid", uid))
		}
	}()
	return fs, nil
}
func (d *followRepository) toDomain(fr dao.Follow) domain.FollowRelation {
	return domain.FollowRelation{
		Followee: fr.Followee,
		Follower: fr.Follower,
	}
}

func (d *followRepository) toEntity(c domain.FollowRelation) dao.Follow {
	return dao.Follow{
		Followee: c.Followee,
		Follower: c.Follower,
	}
}
